/* ospfv3Ipv6Dependencies.h - OSPFv3 list of Macros, externs, etc... used from IPv6 stack*/

/* Copyright 2004 Wind River Systems, Inc. */
#include "copyright_wrs.h"

/*
modification history
--------------------
01g,22mar05,xli remove redeclaration of  "_in_ifaddrhead"
01f,22apr04,ram New branch compile
01e,29sep03,agi added IFP_TO_IA macro
01d,25sep03,ram Second general modifications submission
01c, jul1603,xli replace ifp with sptr_ifnet in "OSPFV3_IA6_TO_IFP" macro
                 to fix the initialize crash issue
01b,16jun03,agi changes to move from Clarinet stack to Accordion stack
01a,14jan03,htm written
*/

#ifndef __INCospfv3Ipv6Dependenciesh
#define __INCospfv3Ipv6Dependenciesh

#ifdef __cplusplus
extern "C" {
#endif

/*#include <unixLib.h>*/

IMPORT  struct ifnethead ifnet_head;

#define OSPFV3_IA6_TO_IFP(ia, ifp)              \
/* struct in6_addr *ia; */              \
/* struct ifnet *ifp; */                \
do {                                    \
    struct ifnet *sptr_ifnet;       \
    struct ifaddr *ifa;                     \
    for (sptr_ifnet = ifnet_head.tqh_first; sptr_ifnet; sptr_ifnet = sptr_ifnet->if_link.tqe_next) { \
        for (ifa = (sptr_ifnet)->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next) {    \
            if (!ifa->ifa_addr)                 \
                continue;                   \
            if ((ifa->ifa_addr->sa_family == AF_INET6)  && \
                IN6_ARE_ADDR_EQUAL(&((struct in6_ifaddr *)ifa)->ia_addr.sin6_addr, (struct in6_addr *)ia))\
                break;                      \
        }      \
        if (sptr_ifnet != NULL)     \
            break;                      \
    }                                   \
   (ifp) = (struct ifnet *)sptr_ifnet;              \
} while (0)

#ifndef INADDR_TO_IFP
#define INADDR_TO_IFP(addr, ifp) \
    /* struct in_addr addr; */ \
    /* struct ifnet *ifp; */ \
{ \
    register struct in_ifaddr *ia; \
\
    for (ia = _in_ifaddrhead.tqh_first; \
        ia != NULL && ((ia->ia_ifp->if_flags & IFF_POINTOPOINT)? \
        IA_DSTSIN(ia):IA_SIN(ia))->sin_addr.s_addr != (addr).s_addr; \
        ia = ia->ia_link.tqe_next) \
         continue; \
    if (ia == NULL) \
        for (ia = _in_ifaddrhead.tqh_first; \
        ia != NULL; \
        ia = ia->ia_link.tqe_next) \
            if (ia->ia_ifp->if_flags & IFF_POINTOPOINT && \
            IA_SIN(ia)->sin_addr.s_addr == (addr).s_addr) \
                break; \
    (ifp) = (ia == NULL) ? NULL : ia->ia_ifp; \
}
#endif

#ifndef IFP_TO_IA6
#define IFP_TO_IA6(ifp, ia)             \
/* struct ifnet *ifp; */                \
/* struct in6_ifaddr *ia; */                \
do {                                    \
    struct ifaddr *ifa;                     \
    for (ifa = (ifp)->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next) {   \
        if (!ifa->ifa_addr)                 \
            continue;                   \
        if (ifa->ifa_addr->sa_family == AF_INET6)       \
            break;                      \
    }                               \
    (ia) = (struct in6_ifaddr *)ifa;                \
} while (0)
#endif

#define OSPFV3_FIND_IN6_LINKLOCAL_IFINDEX(addr) \
    ((addr).s6_addr[2] << 8 | (addr).s6_addr[3])

#define OSPFV3_SET_IN6_LINKLOCAL_IFINDEX(addr, value) \
    do { \
        (addr).s6_addr[2] = ((value) >> 8) & 0xff; \
        (addr).s6_addr[3] = (value) & 0xff; \
    } while (0)


#ifndef IFP_TO_IA
#define IFP_TO_IA(ifp, ia) \
        /* struct ifnet *ifp; */ \
        /* struct in_ifaddr *ia; */ \
{ \
        for ((ia) = TAILQ_FIRST(&_in_ifaddrhead); \
            (ia) != NULL && (ia)->ia_ifp != (ifp); \
            (ia) = TAILQ_NEXT((ia), ia_link)) \
                continue; \
}
#endif
IMPORT struct   ifaddr *ifa_ifwithaddr __P((struct sockaddr *));
IMPORT struct   ifaddr *ifa_ifwithdstaddr __P((struct sockaddr *));
IMPORT struct   ifaddr *ifa_ifwithnet __P((struct sockaddr *));


#ifdef __cplusplus
}
#endif

#endif /* __INCospfv3Ipv6Dependenciesh */
